/*
 * @(#)TransferDictionary.java 1.0 3/30/06
 *
 * Made by LEFT thesis group
 * 
 * Transfer dictionary Module
 * 
 * Transfer dictionary class is the structure of the transfer dictionary that will contain 
 * the translation of words and the transfer rules
 *
 */

package org.dlsu.mt.parser.TRANSFER;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;

import org.dlsu.mt.parser.FStructure;
import org.dlsu.mt.parser.FStructureElement;
import org.dlsu.mt.parser.FStructureElementString;
import org.dlsu.mt.parser.FStructureInterface;

public class TransferDictionary implements TransferDictionaryInterface {
	
				
	public TransferDictionary(){
		
	}

	public String getTransferWord(int id, String lang, String origWord){
		String query = "";
		String word = "";
		
		try{
   			
			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root","");
   			
	        Statement stmt = con.createStatement();
   			
   			
   			if(lang.equals("1"))
   				query = "SELECT * FROM language1Dict WHERE id = "+id+"";
   			else
   				query = "SELECT * FROM language2Dict WHERE id = "+id+"";
   				
   			
   			ResultSet rs = stmt.executeQuery(query);
   			
   			try{
   				
   				rs.next();
   				word = rs.getString("word");
   				rs.close();
   			}catch(Exception err){
   				
   				return origWord;
   			}
   			
   			con.close();
   			stmt.close();
   			
   		}catch(Exception e){}
		return word;
	}
	
	public String getTransferWordPOS(int id, String lang){
		String query = "";
		String pos = "";
		
		try{
   			
			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root","");
	        
   			Statement stmt = con.createStatement();
   			
   			
   			if(lang.equals("1"))
   				query = "SELECT * FROM language1Dict WHERE id = "+id+"";
   			else
   				query = "SELECT * FROM language2Dict WHERE id = "+id+"";
   				
   			
   			ResultSet rs = stmt.executeQuery(query);
   			
   			try{
   				
   				rs.next();
   				pos = rs.getString("pos");
   				rs.close();
   			}catch(Exception err){
   				//System.out.println("Word not found ");
   				return pos;
   			}
   			
   			con.close();
   			stmt.close();
   			
   		}catch(Exception e){}
		return pos;
	}
	
	//retrieves the possible translation words of a certain word. this method will then return an array containing the words
		
	public String[] getPosTranslationWords(String word, String lang, String POS){
		
		//TransferWord tw = getTransferWord(id, lang);
		int arrID[];
		String arrWord[];
		int counter = 0;
		
		try{
   			
			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root",""); 
			
   			Statement stmt = con.createStatement();
   			   			
   			ResultSet rs = stmt.executeQuery("SELECT count(*) AS num FROM transferDict WHERE word = '"+word+"' AND pos = '"+POS+"' AND lang = '"+lang+"' ");
						
			rs.next();			
			counter = rs.getInt("num");
			rs.close();
			
			arrID = new int[counter];
			arrWord = new String[counter];
			
			rs = stmt.executeQuery("SELECT translation FROM transferDict WHERE word = '"+word+"' AND pos = '"+POS+"' AND lang = '"+lang+"' ");
			
			int i = 0;
			while(rs.next()){
				
				arrID[i] = rs.getInt("translation");
				//System.out.println(arrID[i]);
				i++;
			}
			rs.close();
			
			i = 0;
			
			while(i < counter){
				
				if(lang.equals("1"))
					arrWord[i] = getTransferWord(arrID[i], "2", word) + " " + getTransferWordPOS(arrID[i], "2");
				else
					arrWord[i] = getTransferWord(arrID[i], "1", word) + " " + getTransferWordPOS(arrID[i], "1");	
					
				i++;
			}
						
			return arrWord;
			
		}catch(Exception e){
			//System.out.println(e.getMessage());
		}

		return null;
		
	}
		
	public TransferRule createTransferRule(FStructure lang1, FStructure lang2, Vector lang1Vec, Vector lang2Vec, int ruleID, int relatedRuleLang2, int relatedRuleLang1){
		
				
		TransferRule trule = new TransferRule(ruleID + "");
				
		trule.setFStructure(lang1, '1');
		trule.setFStructure(lang2, '2');
		
		if(lang1Vec.size() != 0){
			trule.setRetainedFElements(lang1Vec, '1');
		}
		
		if(lang2Vec.size() != 0){
			trule.setRetainedFElements(lang2Vec, '2');
		}
		
		trule.setRelatedRuleLang2(relatedRuleLang2);
		trule.setRelatedRuleLang1(relatedRuleLang1);
		
		return trule;
		
	}
	
	public void WordLookup(){		
		
	}
	
	
	public int getMaxRuleID(){
		
		String query = null;
		int id = 0;
   		String msg = "";
   		
   		try{
   			
   			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root","");
	        
   			Statement stmt = con.createStatement();
   			   			
   			ResultSet rs = stmt.executeQuery("SELECT max(ruleID) AS id FROM transferRules");
				
			try
			{
				rs.next();
				id = rs.getInt( "id" );
				rs.close();
			} catch ( SQLException e ) {
				//System.out.println(e.getMessage());
			}
			
			stmt.close();
			con.close();
			
   		}catch(Exception e)
		{
			System.out.println("Error "+e.toString());
		}
		
		return id;	
	}
	
	public String getRelatedRule(int id, String lang){
		
		String query = "", strTemp = "";
		int relatedRule = 0;
		
		try{
			
			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root","");
			
   			Statement stmt = con.createStatement();   			
   			
   			query = "SELECT * FROM transferRules where ruleID = "+id+"";
   			   				
   			ResultSet rs = stmt.executeQuery(query);   			
   			
   			try{
   				
   				rs.next();
   				
   				if(lang.equals("1")){
   					strTemp = rs.getString("language1Rule");
   					relatedRule = rs.getInt("relatedRuleLang1");
   					
   					if(relatedRule != 0)
   						strTemp = strTemp + getRelatedRule(relatedRule, "1");
   				}
   				else{
   					
   					strTemp = rs.getString("language2Rule");
   					relatedRule = rs.getInt("relatedRuleLang2");
   					
   					if(relatedRule != 0)
   						strTemp = strTemp + getRelatedRule(relatedRule, "2");
   				}  				
   				   				
   				rs.close();
   				
   			}catch(SQLException sqle){
   				
   			}
   			
   			con.close();
   			stmt.close();   			
   			
   		}catch(Exception e){
   			
   		}
		
		return strTemp;
		
	}
	
	public TransferRule getTransferRule(int id){
		
		String query = null;
		TransferRule tr;
		FStructure lang1, lang2;
		String strLang1 = "", strLang2 = "", strRetLang1 = "", strRetLang2 = "";
		int ruleID;
		int relatedRuleLang2, relatedRuleLang1;
		String strElementPosition = "";

		Vector lang1V = new Vector(), lang2V = new Vector();
		
		try{
			
			Class.forName("com.mysql.jdbc.Driver");
	        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leftDB", "root","");
			
   			Statement stmt = con.createStatement();   			
   			
   			query = "SELECT * FROM transferRules where ruleID = "+id+"";
   			   				
   			ResultSet rs = stmt.executeQuery(query);   			
   			
			try
			{
				rs.next();
				
				strLang1 = rs.getString("language1Rule");
				strLang2 = rs.getString("language2Rule");
				
				ruleID = rs.getInt("ruleID");
				
				relatedRuleLang2 = rs.getInt("relatedRuleLang2");
				relatedRuleLang1 = rs.getInt("relatedRuleLang1");
				strRetLang1 = rs.getString("retainedLang1FElements");
				strRetLang2 = rs.getString("retainedLang2FElements");
				
				strElementPosition = rs.getString("fElementPositions");			
				
				
				if(strLang1.equals("") || strLang2.equals("")){
					return null;
				}
				
				
				if(relatedRuleLang2 != 0){
					
					strLang2 = strLang2 + getRelatedRule(relatedRuleLang2, "2");
					
				}
				
				if(relatedRuleLang1 != 0){
					
					strLang1 = strLang1 + getRelatedRule(relatedRuleLang1, "1");
				}
				
				lang1 = parseToFStructure(strLang1);
				//System.out.println("lampas sa eng");
				lang2 = parseToFStructure(strLang2);
				//System.out.println("lampas sa fil");
				if(lang1 == null || lang2 == null)
					return null;
					
				
				if(strElementPosition != null && !strElementPosition.equals("")){
					
					String arr[] = strElementPosition.split(" ");
					
					for(int i = 0; i < arr.length; i++){		
						lang1 = setPosition(lang1, arr[i]);
						lang2 = setPosition(lang2, arr[i]);					
					}					
				}
				
				
				//if(id == 20)
				//	display(eng);
											
				if(strRetLang1 == null)
					strRetLang1 = "";
				
				if(strRetLang2 == null)
					strRetLang2 = "";
					
				lang1V = parseToFElement(strRetLang1);
				lang2V = parseToFElement(strRetLang2);
										
				tr = createTransferRule(lang1, lang2, lang1V, lang2V, ruleID, relatedRuleLang2, relatedRuleLang1);
						
				rs.close();
				
			} catch ( SQLException e ) {
				//System.out.println(e.getMessage() + " TRANSFER RULE NOT FOUND!");
				
				return null;
			}			
			stmt.close();
			con.close();
			
			return tr;
		
		}catch(Exception e){
			//System.out.println(e.getMessage());
			return null;
			//System.out.println("ERROR LOADING TRANSFER RULES");
		}
	}	

	public Vector parseToFElement(String text){
		
		Vector temp = new Vector();
		StringTokenizer st = new StringTokenizer(text);
		String strTemp = "", name = "";
		
		FStructureElement fse;
		int i = 0;
		
		try{			
			while(st.hasMoreElements()){
				
				strTemp = st.nextToken();
				
				while(strTemp.charAt(i) != '=')											
					i++;
				
				name = strTemp.substring(0, i);
				//content = new FStructureElementString(strTemp.substring(i+1));
				fse = new FStructureElement(name);
				fse.addElement(new FStructureElementString("PRED\t" + strTemp.substring(i+5)));
				
				temp.add(fse);
				//System.out.println(name + " = " + strTemp.substring(i+1));
			}			
		}
		catch(Exception e){
			
		}
		
		//System.out.println(temp.size());
		
		return temp;
	}
	
	public FStructure parseToFStructure(String text){
			
		int i = 0;
		int bFlag = 0;
		FStructureElement checker2;
		FStructure root, checker;
		String strTemp, title, position;
		boolean skip = false, bFound = false;
		
		StringTokenizer st = new StringTokenizer(text);
		Vector fs = new Vector(), fe = new Vector();
		
		position = st.nextToken();		
		title = st.nextToken();
		root = new FStructure(title);
			
		try{
			
			while(st.hasMoreElements()){
				
				strTemp = st.nextToken();
				
				if(bFlag == 0){
					if(!strTemp.equals("FS:"))
						return null;
				}			
				
				//System.out.print(strTemp + " TITLE!");
				
				if(strTemp.equals("FS:")){
					bFlag = 1; 
					skip = true;
				}
				else if(strTemp.equals("FE:")){
						bFlag = 2; 
						skip = true;
					}
				else if(strTemp.equals("FORMAT:")){
						bFlag = 3; 
						skip = true;
					}
				//System.out.println(bFlag + strTemp);
				
				
				if(!skip){					
					
					if(bFlag == 1){
						//System.out.println(bFlag + strTemp);
						fs.addElement(new FStructure(strTemp));
					}
					else if(bFlag == 2){
							fe.addElement(new FStructureElement(strTemp));
							//System.out.println(bFlag + strTemp);
						}
					else if(bFlag == 3){						
							
							//System.out.println(fs.size() + strTemp);					
							bFound = false;
							try{
								i = 0;							
								while(i < fs.size() && !bFound){									
									
									checker = (FStructure)fs.elementAt(i);
									//System.out.println(checker.getName());
									if(strTemp.startsWith(checker.getName())){
										bFound = true;
										root = checker;
										fs.remove(checker);
										strTemp = strTemp.substring(checker.getName().length());
										//System.out.println(strTemp + " " + checker.getName());
										
										while(strTemp.length() > 0){
											//System.out.println(strTemp + " " + checker.getName());
											
											for(int a = 0; a < fs.size(); a++){
												checker = (FStructure)fs.elementAt(a);
												if(strTemp.startsWith(checker.getName())){
													strTemp = strTemp.substring(checker.getName().length());
													root.addEntry(checker);
													//System.out.println(strTemp + " " + checker.getName());
												}	
											}
											
											for(int b = 0; b < fe.size(); b++){
												checker2 = (FStructureElement)fe.elementAt(b);
												if(strTemp.startsWith(checker2.getName())){
													strTemp = strTemp.substring(checker2.getName().length());
													
													String key = checker2.getName();													
													
													if(key.endsWith("1") || key.endsWith("2") || key.endsWith("3") || key.endsWith("4") || key.endsWith("5") || key.endsWith("6") || key.endsWith("7") || key.endsWith("8") || key.endsWith("9") ){			
														key = key.substring(0, key.length() - 1);
														checker2.setName(key);
													}
													
													root.addEntry(checker2);
													//System.out.println("pumasok dito");
												}
											}											
										}
																				
										fs.addElement(root);										
									}								
									i++;
								}
								if(!bFound){
									return null;
								}
														
							}
							catch(Exception er){
								System.out.println(er.getMessage());
							}
						}
				}
				
				skip = false;				
			}
			
			root = (FStructure)fs.lastElement();
			
			root.setPosition(position);
			return renameElements(root);
		}
		catch(Exception e){
		}
						
		return root;		
	}
	
	public void display(FStructure f){
		
		FStructureInterface fsi;
		FStructure fstruct;
		String key;
		
		Enumeration e = f.values.keys();
		
		for(int i = 0; i < f.values.size();i++){
			key = (String)e.nextElement();
			fsi = f.getEntry(key);
			
				
			if (fsi instanceof FStructure){
				
				fstruct = (FStructure)fsi;
				if(fstruct.values.size() != 0){
					
					System.out.println(fsi.getName() + " value of " + f.getName());
					display(fstruct);				
				}				
			}
			else if(fsi instanceof FStructureElement){
			
				System.out.println(fsi.getName() + " value of " + f.getName());
				FStructureElement element = (FStructureElement)fsi;
				
				System.out.println(element.values.toString());
				//System.out.println(element.getPrevParentPosition() + " prev val");
				
			}
			
		}
	}
	
	public FStructure setPosition(FStructure f, String pos){
		
		FStructureInterface fsi;
		String key, position = pos;
		FStructure temp = (FStructure)f;
		Enumeration e = temp.values.keys();		
		
		//for(int i = 0; i < f.values.size();i++){
		while(e.hasMoreElements()){
			
			key = (String)e.nextElement();
			fsi = temp.getEntry(key);
			
			if (fsi instanceof FStructureElement){
				FStructureElement fsiElement = (FStructureElement)fsi;
				
				//System.out.println(fsiElement.getPrevParentPosition() + " ito ang prev position");
				
				if(position.startsWith(fsiElement.getName())){
					
					position = position.replace(fsiElement.getName(), "");
					
					if(position.startsWith(f.getName())){
						position = position.substring(f.getName().length(), position.length());
						fsiElement.setPrevParentPosition(position);
						//System.out.println(fsiElement.getPrevParentPosition());
						temp.values.remove(key);
						temp.values.put(key, fsiElement);											
					}
					else if(position.endsWith(f.getName())){
						
						position = position.substring(0, position.length() - f.getName().length());
						
						fsiElement.setPrevParentPosition(position);
						//System.out.println(key + " here it is");
						//System.out.println(fsiElement.getPrevParentPosition());
						temp.values.remove(key);
						temp.values.put(key, fsiElement);											
					}
				}				
			}	
			else if(fsi instanceof FStructure){
					
				fsi = setPosition((FStructure)fsi, pos);
				temp.values.remove(key);				
				temp.values.put(key, fsi);				
			}				
		}		
		
		return temp;		
	}
	
	public FStructure renameElements(FStructure f){
		
		FStructureInterface fsi;
		FStructure fstruct;
		FStructure temp = (FStructure)f.clone();
		String key;
		
		Enumeration e = temp.values.keys();
		
		//for(int i = 0; i < temp.values.size();i++){
			
		while(e.hasMoreElements()){
			
			key = (String)e.nextElement();
			fsi = temp.getEntry(key);
			
			temp.values.remove(key);
			//key = fsi.getName();
			
			//System.out.println(key + " struct");
			
			if(key.endsWith(".1") || key.endsWith(".2") || key.endsWith(".3") || key.endsWith(".4") || key.endsWith(".5") || key.endsWith(".6") || key.endsWith(".7") || key.endsWith(".8") || key.endsWith(".9") ){			
					key = key.substring(0, key.length() - 2);			
			}			
			
			fsi.setName(key);			
					
			if (fsi instanceof FStructure){
								
				temp.addEntry(renameElements((FStructure)fsi));
				//System.out.println(key + " struct");					
				
			}
			else if(fsi instanceof FStructureElement){
			
				temp.addEntry(fsi);
				//System.out.println(key + " felem");
			}
			
		}		
		return temp;
	}
	
	
}